﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ESSManageService.Common.Helper;
using Microsoft.Extensions.Hosting;
using Serilog.Sinks.SystemConsole.Themes;
using Serilog;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using ESSManageService.IServices;
using Microsoft.AspNetCore.Http;

namespace ESSManageService.Extensions
{
    public static class JwtSetup
    {
        //添加认证服务
        public static IServiceCollection AddJwtSetup(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));

            // 添加认证服务
            services.AddAuthentication(options =>
            {
                options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            })
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,
                    ValidIssuer = AppSettings.GetValue("Jwt:Issuer"),
                    ValidAudience = AppSettings.GetValue("Jwt:Audience"),
                    IssuerSigningKey = new SymmetricSecurityKey(
                    Encoding.UTF8.GetBytes(AppSettings.GetValue("Jwt:Key"))),
                    // 添加时间偏差容错设置
                    ClockSkew = TimeSpan.FromMinutes(5), // 允许5分钟时间偏差
                    //ClockSkew = TimeSpan.Zero,  // 改为不宽容时间偏差
                    // 添加时区转换处理
                    LifetimeValidator = (before, expires, token, param) =>
                    {
                        var now = DateTime.Now; // 使用本地时间
                        return now <= expires?.ToLocalTime();
                    }
                };

                // 添加黑名单检查
                options.Events = new JwtBearerEvents
                {
                    OnMessageReceived = async context =>
                    {
                        // 手动从请求头获取令牌
                        var authorization = context.Request.Headers["Authorization"].ToString();
                        if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
                        {
                            context.Token = authorization.Substring("Bearer ".Length).Trim();
                        }

                        try
                        {
                            var blacklistService = context.HttpContext.RequestServices.GetRequiredService<ITokenBlacklistService>();

                            if (string.IsNullOrEmpty(context.Token))
                            {
                                context.Fail("缺少访问令牌");
                                return;
                            }

                            // 添加详细日志记录
                            if (await blacklistService.IsTokenBlacklistedAsync(context.Token))
                            {
                                context.Response.Headers.Append("X-Token-Status", "revoked");
                                context.Fail("令牌已失效");
                            }
                        }
                        catch (Exception ex)
                        {
                            context.Fail("服务器认证错误");
                        }
                    }
                };
            });

            return services;
        }
    }
}
